import 'dart:io';

import 'package:bot_toast/bot_toast.dart';
import 'package:dio/dio.dart';
import 'package:mahjong/entity/AbstractFormart.dart';
import 'package:mahjong/entity/AbstractResult.dart';
import 'package:mahjong/entity/Restful.dart';
import 'package:mahjong/entity/UserEntityInfo.dart';
import 'package:mahjong/page/UserLoginWidget.dart';
import 'package:mahjong/util/CustomNavigatorObserver.dart';
import 'package:mahjong/util/CustomRoute.dart';
import 'package:mahjong/util/CustomerDialog.dart';
import 'package:mahjong/const/BusinessEnum.dart';
import 'DictionaryConst.dart';
import 'package:mahjong/util/UserUtil.dart';

typedef _callBack<T> = void Function(T data);

class Http {
  static Http instance;
  static String token;
  static final int receiveTimeout = 2000;
  static final int connectTimeout = 2000;
  static Dio _dio;
  BaseOptions _options;

  static Http getInstance() {
    if (instance == null) {
      instance = new Http._();
    }
    return instance;
  }

  Http._() {
    // 初始化 Options
    _options = BaseOptions(
        baseUrl: DictionaryConst.localHostHttp,
        sendTimeout: connectTimeout,
        receiveTimeout: receiveTimeout,
        contentType: "application/json",
        headers: {});

    _dio = new Dio(_options);

    _dio.interceptors.add(InterceptorsWrapper(onRequest: (options, handler) {
      UserEntityInfo userEntityInfo = UserUtil.getUserInfo();
      if (null != userEntityInfo) {
        options.headers["Authory"] = userEntityInfo.tokenAuthority;
      }
      return handler.next(options);
    }, onResponse: (response, handler) {
      return handler.next(response);
    }, onError: (DioError e, handler) {
      return handler.next(e);
    }));
  }

  request<T extends AbstractResult<T>>(url,
      {
      // 返回内容格式
      ResponseType responseType,
      data,
      RequestEnum type = RequestEnum.GET,
      // 请求内容格式
      ContentType contentType,
      T resultEntity,
      cancelToken,
      // 成功回调
      _callBack<T> success,
      // 失败回调
      _callBack<T> error,
      bool showLoading = false,
      bool showErrorMsg = false,
      String loadingMsg = "加载中..."}) async {
    if (contentType == null) {
      contentType = ContentType.json;
    }
    if (showLoading) {
      CustomerDialog.loading(loadingMsg);
    }
    Response response;
    Options options = Options(
        sendTimeout: connectTimeout,
        receiveTimeout: receiveTimeout,
        responseType: responseType != null ? responseType : ResponseType.json,
        contentType: contentType.toString());
    try {
      if (type == RequestEnum.GET) {
        response = await _dio.get(url,
            queryParameters: data, options: options, cancelToken: cancelToken);
      } else {
        response = await _dio.post(url, data: data, options: options);
      }
      CustomerDialog.closeAllLoading();
      if (response.data is Map) {
        resultEntity = resultEntity ?? new Restful();
        T result = resultEntity?.formJSON(response.data);
        if (result is Restful &&
            (result as Restful).code != BusinessEnum.success) {
          if (showErrorMsg) {
            CustomerDialog.showText((result as Restful).msg);
          }
          error(result);
        } else {
          success(result);
        }
      } else {
        success(response.data);
      }
    } on DioError catch (e) {
      CustomerDialog.closeAllLoading();
      if (CancelToken.isCancel(e)) {
        print('get请求取消! ' + e.message);
      } else {
        print('get请求发生错误：$e');
      }
      if (e.type.index == 5 || e.response == null) {
        CustomerDialog.showText("网络异常");
        error(null);
        return;
      }
      if (e.response.statusCode == HttpStatus.unauthorized) {
        CustomNavigatorObserver.getInstance().navigator.pushAndRemoveUntil(
            new CustomRoute(UserLoginWidget(), AnimationEnum.zoom),
            (route) => route == null);
      } else if (e.response.statusCode != HttpStatus.ok) {
        error(e.response.data);
      }
    }
  }
}

enum RequestEnum { POST, GET }
